package org.liuyuantao.lucene.index;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.BytesRef;
import org.apache.tika.Tika;
import org.liuyuantao.lucene.utils.IKAnalyzer5x;

/**
 * 创建索引HelloWorld
 *
 * @author liuyuantao
 */
public class IndexExample {

    private IndexWriter writer; // 写索引实例

    /**
     * 构造方法 实例化IndexWriter
     *
     * @param indexDir
     * @throws Exception
     */
    public IndexExample(String indexDir) throws Exception {
        // 创建索引存储的路径
        Directory dir = FSDirectory.open(Paths.get(indexDir));
        // 使用分词器
        //Analyzer analyzer = new StandardAnalyzer(); // 标准分词器
        //中文分词器
        Analyzer analyzer = new IKAnalyzer5x(true);
        // 写索引配置
        IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
        writer = new IndexWriter(dir, iwc);
    }

    /**
     * 关闭写索引
     *
     * @throws Exception
     */
    public void close() {
        try {
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 索引指定目录的所有文件
     *
     * @param dataDir
     * @throws Exception
     */
    public int makeIndex(String dataDir) throws Exception {
        Path path = Paths.get(dataDir).toAbsolutePath();
        writer.deleteAll();
        File[] fileList = path.toFile().listFiles();
        if (fileList != null && fileList.length > 0) {
            for (File f : fileList) {
                indexFile(f);
            }
        }
        int numIndexed = writer.numDocs();
        this.close();
        return numIndexed;
    }

    /**
     * 索引指定文件
     *
     * @param f
     */
    private void indexFile(File f) throws Exception {
        System.out.println("正在索引文件:" + f.getCanonicalPath());
        Document doc = getDocument(f);
        writer.addDocument(doc);
    }

    /**
     * 获取文档，文档里再设置每个字段
     *
     * @param f
     */
    private Document getDocument(File f) throws Exception {
        // 创建Document对象
        Document doc = new Document();
        // 向Document添加Field
        TextField textField = new TextField("content", new Tika().parse(f));
        Random ran = new Random();
        // 加权
        textField.setBoost(1.5f);
        int score = ran.nextInt(800);
        doc.add(textField);
        doc.add(new StringField("name", f.getName(), Field.Store.YES));
        doc.add(new BinaryDocValuesField("sortName", new BytesRef(f.getName().getBytes())));
        doc.add(new StringField("path", f.getCanonicalPath(), Field.Store.YES));
        //Sort排序对索引字段有了新的要求,即使用DocValuesField的字段才能进行排序
        doc.add(new NumericDocValuesField("sortDate", f.lastModified()));
        //如果想在查询中获取ID的字段值,那就多加一条排序的字段，那保留原代码
        doc.add(new LongField("date", f.lastModified(), Field.Store.YES));
        doc.add(new NumericDocValuesField("sortSize", f.length()));
        doc.add(new LongField("size", f.length(), Field.Store.YES));
        doc.add(new NumericDocValuesField("score", score));
        return doc;
    }
}
